home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / dns / resolver.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  601 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import socket
  5. import sys
  6. import time
  7. import dns.exception as dns
  8. import dns.message as dns
  9. import dns.name as dns
  10. import dns.query as dns
  11. import dns.rcode as dns
  12. import dns.rdataclass as dns
  13. import dns.rdatatype as dns
  14. if sys.platform == 'win32':
  15.     import _winreg
  16.  
  17.  
  18. class NXDOMAIN(dns.exception.DNSException):
  19.     pass
  20.  
  21. Timeout = dns.exception.Timeout
  22.  
  23. class NoAnswer(dns.exception.DNSException):
  24.     pass
  25.  
  26.  
  27. class NoNameservers(dns.exception.DNSException):
  28.     pass
  29.  
  30.  
  31. class NotAbsolute(dns.exception.DNSException):
  32.     pass
  33.  
  34.  
  35. class NoRootSOA(dns.exception.DNSException):
  36.     pass
  37.  
  38.  
  39. class Answer(object):
  40.     
  41.     def __init__(self, qname, rdtype, rdclass, response):
  42.         self.qname = qname
  43.         self.rdtype = rdtype
  44.         self.rdclass = rdclass
  45.         self.response = response
  46.         min_ttl = -1
  47.         rrset = None
  48.         for count in xrange(0, 15):
  49.             
  50.             try:
  51.                 rrset = response.find_rrset(response.answer, qname, rdclass, rdtype)
  52.                 if min_ttl == -1 or rrset.ttl < min_ttl:
  53.                     min_ttl = rrset.ttl
  54.                 
  55.             continue
  56.             except KeyError:
  57.                 if rdtype != dns.rdatatype.CNAME:
  58.                     
  59.                     try:
  60.                         crrset = response.find_rrset(response.answer, qname, rdclass, dns.rdatatype.CNAME)
  61.                         if min_ttl == -1 or crrset.ttl < min_ttl:
  62.                             min_ttl = crrset.ttl
  63.                         
  64.                         for rd in crrset:
  65.                             qname = rd.target
  66.                             break
  67.                         
  68.                     except KeyError:
  69.                         raise NoAnswer
  70.                     except:
  71.                         None<EXCEPTION MATCH>KeyError
  72.                     
  73.  
  74.                 None<EXCEPTION MATCH>KeyError
  75.                 raise NoAnswer
  76.                 continue
  77.             
  78.  
  79.         
  80.         if rrset is None:
  81.             raise NoAnswer
  82.         
  83.         self.rrset = rrset
  84.         self.expiration = time.time() + min_ttl
  85.  
  86.     
  87.     def __getattr__(self, attr):
  88.         if attr == 'name':
  89.             return self.rrset.name
  90.         elif attr == 'ttl':
  91.             return self.rrset.ttl
  92.         elif attr == 'covers':
  93.             return self.rrset.covers
  94.         elif attr == 'rdclass':
  95.             return self.rrset.rdclass
  96.         elif attr == 'rdtype':
  97.             return self.rrset.rdtype
  98.         else:
  99.             raise AttributeError, attr
  100.  
  101.     
  102.     def __len__(self):
  103.         return len(self.rrset)
  104.  
  105.     
  106.     def __iter__(self):
  107.         return iter(self.rrset)
  108.  
  109.     
  110.     def __getitem__(self, i):
  111.         return self.rrset[i]
  112.  
  113.     
  114.     def __delitem__(self, i):
  115.         del self.rrset[i]
  116.  
  117.     
  118.     def __getslice__(self, i, j):
  119.         return self.rrset[i:j]
  120.  
  121.     
  122.     def __delslice__(self, i, j):
  123.         del self.rrset[i:j]
  124.  
  125.  
  126.  
  127. class Cache(object):
  128.     
  129.     def __init__(self, cleaning_interval = 300):
  130.         self.data = { }
  131.         self.cleaning_interval = cleaning_interval
  132.         self.next_cleaning = time.time() + self.cleaning_interval
  133.  
  134.     
  135.     def maybe_clean(self):
  136.         now = time.time()
  137.         if self.next_cleaning <= now:
  138.             keys_to_delete = []
  139.             for k, v in self.data.iteritems():
  140.                 if v.expiration <= now:
  141.                     keys_to_delete.append(k)
  142.                     continue
  143.             
  144.             for k in keys_to_delete:
  145.                 del self.data[k]
  146.             
  147.             now = time.time()
  148.             self.next_cleaning = now + self.cleaning_interval
  149.         
  150.  
  151.     
  152.     def get(self, key):
  153.         self.maybe_clean()
  154.         v = self.data.get(key)
  155.         if v is None or v.expiration <= time.time():
  156.             return None
  157.         
  158.         return v
  159.  
  160.     
  161.     def put(self, key, value):
  162.         self.maybe_clean()
  163.         self.data[key] = value
  164.  
  165.     
  166.     def flush(self, key = None):
  167.         if key is not None:
  168.             if self.data.has_key(key):
  169.                 del self.data[key]
  170.             
  171.         else:
  172.             self.data = { }
  173.             self.next_cleaning = time.time() + self.cleaning_interval
  174.  
  175.  
  176.  
  177. class Resolver(object):
  178.     
  179.     def __init__(self, filename = '/etc/resolv.conf', configure = True):
  180.         self.reset()
  181.         if configure:
  182.             if sys.platform == 'win32':
  183.                 self.read_registry()
  184.             elif filename:
  185.                 self.read_resolv_conf(filename)
  186.             
  187.         
  188.  
  189.     
  190.     def reset(self):
  191.         self.domain = dns.name.Name(dns.name.from_text(socket.gethostname())[1:])
  192.         if len(self.domain) == 0:
  193.             self.domain = dns.name.root
  194.         
  195.         self.nameservers = []
  196.         self.search = []
  197.         self.port = 53
  198.         self.timeout = 2
  199.         self.lifetime = 30
  200.         self.keyring = None
  201.         self.keyname = None
  202.         self.edns = -1
  203.         self.ednsflags = 0
  204.         self.payload = 0
  205.         self.cache = None
  206.  
  207.     
  208.     def read_resolv_conf(self, f):
  209.         if isinstance(f, str) or isinstance(f, unicode):
  210.             
  211.             try:
  212.                 f = open(f, 'r')
  213.             except IOError:
  214.                 self.nameservers = [
  215.                     '127.0.0.1']
  216.                 return None
  217.  
  218.             want_close = True
  219.         else:
  220.             want_close = False
  221.         
  222.         try:
  223.             for l in f:
  224.                 if len(l) == 0 and l[0] == '#' or l[0] == ';':
  225.                     continue
  226.                 
  227.                 tokens = l.split()
  228.                 if len(tokens) == 0:
  229.                     continue
  230.                 
  231.                 if tokens[0] == 'nameserver':
  232.                     self.nameservers.append(tokens[1])
  233.                     continue
  234.                 if tokens[0] == 'domain':
  235.                     self.domain = dns.name.from_text(tokens[1])
  236.                     continue
  237.                 if tokens[0] == 'search':
  238.                     for suffix in tokens[1:]:
  239.                         self.search.append(dns.name.from_text(suffix))
  240.                     
  241.         finally:
  242.             if want_close:
  243.                 f.close()
  244.             
  245.  
  246.         if len(self.nameservers) == 0:
  247.             self.nameservers.append('127.0.0.1')
  248.         
  249.  
  250.     
  251.     def _determine_split_char(self, entry):
  252.         if entry.find(' ') >= 0:
  253.             split_char = ' '
  254.         elif entry.find(',') >= 0:
  255.             split_char = ','
  256.         else:
  257.             split_char = ' '
  258.         return split_char
  259.  
  260.     
  261.     def _config_win32_nameservers(self, nameservers):
  262.         nameservers = str(nameservers)
  263.         split_char = self._determine_split_char(nameservers)
  264.         ns_list = nameservers.split(split_char)
  265.         for ns in ns_list:
  266.             if ns not in self.nameservers:
  267.                 self.nameservers.append(ns)
  268.                 continue
  269.         
  270.  
  271.     
  272.     def _config_win32_domain(self, domain):
  273.         self.domain = dns.name.from_text(str(domain))
  274.  
  275.     
  276.     def _config_win32_search(self, search):
  277.         search = str(search)
  278.         split_char = self._determine_split_char(search)
  279.         search_list = search.split(split_char)
  280.         for s in search_list:
  281.             if s not in self.search:
  282.                 self.search.append(dns.name.from_text(s))
  283.                 continue
  284.         
  285.  
  286.     
  287.     def _config_win32_fromkey(self, key):
  288.         
  289.         try:
  290.             (servers, rtype) = _winreg.QueryValueEx(key, 'NameServer')
  291.         except WindowsError:
  292.             servers = None
  293.  
  294.         if servers:
  295.             self._config_win32_nameservers(servers)
  296.             
  297.             try:
  298.                 (dom, rtype) = _winreg.QueryValueEx(key, 'Domain')
  299.                 if dom:
  300.                     self._config_win32_domain(servers)
  301.             except WindowsError:
  302.                 pass
  303.             except:
  304.                 None<EXCEPTION MATCH>WindowsError
  305.             
  306.  
  307.         None<EXCEPTION MATCH>WindowsError
  308.         
  309.         try:
  310.             (servers, rtype) = _winreg.QueryValueEx(key, 'DhcpNameServer')
  311.         except WindowsError:
  312.             servers = None
  313.  
  314.         if servers:
  315.             self._config_win32_nameservers(servers)
  316.             
  317.             try:
  318.                 (dom, rtype) = _winreg.QueryValueEx(key, 'DhcpDomain')
  319.                 if dom:
  320.                     self._config_win32_domain(servers)
  321.             except WindowsError:
  322.                 pass
  323.             except:
  324.                 None<EXCEPTION MATCH>WindowsError
  325.             
  326.  
  327.         None<EXCEPTION MATCH>WindowsError
  328.         
  329.         try:
  330.             (search, rtype) = _winreg.QueryValueEx(key, 'SearchList')
  331.         except WindowsError:
  332.             search = None
  333.  
  334.         if search:
  335.             self._config_win32_search(search)
  336.         
  337.  
  338.     
  339.     def read_registry(self):
  340.         lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
  341.         want_scan = False
  342.         
  343.         try:
  344.             tcp_params = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters')
  345.             want_scan = True
  346.         except EnvironmentError:
  347.             tcp_params = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP')
  348.         
  349.  
  350.         
  351.         try:
  352.             self._config_win32_fromkey(tcp_params)
  353.         finally:
  354.             tcp_params.Close()
  355.  
  356.         if want_scan:
  357.             interfaces = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces')
  358.             
  359.             try:
  360.                 i = 0
  361.                 while True:
  362.                     
  363.                     try:
  364.                         guid = _winreg.EnumKey(interfaces, i)
  365.                         i += 1
  366.                         key = _winreg.OpenKey(interfaces, guid)
  367.                         if not self._win32_is_nic_enabled(lm, guid, key):
  368.                             continue
  369.                         
  370.                         
  371.                         try:
  372.                             self._config_win32_fromkey(key)
  373.                         finally:
  374.                             key.Close()
  375.  
  376.                     continue
  377.                     except EnvironmentError:
  378.                         break
  379.                         continue
  380.                     
  381.  
  382.                     None<EXCEPTION MATCH>EnvironmentError
  383.             finally:
  384.                 interfaces.Close()
  385.  
  386.         lm.Close()
  387.  
  388.     
  389.     def _win32_is_nic_enabled(self, lm, guid, interface_key):
  390.         
  391.         try:
  392.             connection_key = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection' % guid)
  393.             
  394.             try:
  395.                 (pnp_id, ttype) = _winreg.QueryValueEx(connection_key, 'PnpInstanceID')
  396.                 if ttype != _winreg.REG_SZ:
  397.                     raise ValueError
  398.                 
  399.                 device_key = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Enum\\%s' % pnp_id)
  400.                 
  401.                 try:
  402.                     (flags, ttype) = _winreg.QueryValueEx(device_key, 'ConfigFlags')
  403.                     if ttype != _winreg.REG_DWORD:
  404.                         raise ValueError
  405.                     
  406.                     return not (flags & 1)
  407.                 finally:
  408.                     device_key.Close()
  409.  
  410.             finally:
  411.                 connection_key.Close()
  412.  
  413.         except (EnvironmentError, ValueError):
  414.             
  415.             try:
  416.                 (nte, ttype) = _winreg.QueryValueEx(interface_key, 'NTEContextList')
  417.                 return nte is not None
  418.             except WindowsError:
  419.                 return False
  420.             except:
  421.                 None<EXCEPTION MATCH>WindowsError
  422.             
  423.  
  424.             None<EXCEPTION MATCH>WindowsError
  425.  
  426.  
  427.     
  428.     def _compute_timeout(self, start):
  429.         now = time.time()
  430.         if now < start:
  431.             if start - now > 1:
  432.                 raise Timeout
  433.             else:
  434.                 now = start
  435.         
  436.         duration = now - start
  437.         if duration >= self.lifetime:
  438.             raise Timeout
  439.         
  440.         return min(self.lifetime - duration, self.timeout)
  441.  
  442.     
  443.     def query(self, qname, rdtype = dns.rdatatype.A, rdclass = dns.rdataclass.IN, tcp = False):
  444.         if isinstance(qname, (str, unicode)):
  445.             qname = dns.name.from_text(qname, None)
  446.         
  447.         if isinstance(rdtype, str):
  448.             rdtype = dns.rdatatype.from_text(rdtype)
  449.         
  450.         if isinstance(rdclass, str):
  451.             rdclass = dns.rdataclass.from_text(rdclass)
  452.         
  453.         qnames_to_try = []
  454.         if qname.is_absolute():
  455.             qnames_to_try.append(qname)
  456.         elif len(qname) > 1:
  457.             qnames_to_try.append(qname.concatenate(dns.name.root))
  458.         
  459.         if self.search:
  460.             for suffix in self.search:
  461.                 qnames_to_try.append(qname.concatenate(suffix))
  462.             
  463.         else:
  464.             qnames_to_try.append(qname.concatenate(self.domain))
  465.         all_nxdomain = True
  466.         start = time.time()
  467.         for qname in qnames_to_try:
  468.             if self.cache:
  469.                 answer = self.cache.get((qname, rdtype, rdclass))
  470.                 if answer:
  471.                     return answer
  472.                 
  473.             
  474.             request = dns.message.make_query(qname, rdtype, rdclass)
  475.             if self.keyname is not None:
  476.                 request.use_tsig(self.keyring, self.keyname)
  477.             
  478.             request.use_edns(self.edns, self.ednsflags, self.payload)
  479.             response = None
  480.             nameservers = self.nameservers[:]
  481.             backoff = 0.1
  482.             while response is None:
  483.                 if len(nameservers) == 0:
  484.                     raise NoNameservers
  485.                 
  486.                 for nameserver in nameservers[:]:
  487.                     timeout = self._compute_timeout(start)
  488.                     
  489.                     try:
  490.                         if tcp:
  491.                             response = dns.query.tcp(request, nameserver, timeout, self.port)
  492.                         else:
  493.                             response = dns.query.udp(request, nameserver, timeout, self.port)
  494.                     except (socket.error, dns.exception.Timeout):
  495.                         response = None
  496.                         continue
  497.                     except dns.query.UnexpectedSource:
  498.                         response = None
  499.                         continue
  500.                     except dns.exception.FormError:
  501.                         nameservers.remove(nameserver)
  502.                         response = None
  503.                         continue
  504.  
  505.                     rcode = response.rcode()
  506.                     if rcode == dns.rcode.NOERROR or rcode == dns.rcode.NXDOMAIN:
  507.                         break
  508.                     
  509.                     if rcode != dns.rcode.SERVFAIL:
  510.                         nameservers.remove(nameserver)
  511.                     
  512.                     response = None
  513.                 
  514.                 if response is not None:
  515.                     break
  516.                 
  517.                 if len(nameservers) > 0:
  518.                     timeout = self._compute_timeout(start)
  519.                     sleep_time = min(timeout, backoff)
  520.                     backoff *= 2
  521.                     time.sleep(sleep_time)
  522.                     continue
  523.             if response.rcode() == dns.rcode.NXDOMAIN:
  524.                 continue
  525.             
  526.             all_nxdomain = False
  527.             break
  528.         
  529.         if all_nxdomain:
  530.             raise NXDOMAIN
  531.         
  532.         answer = Answer(qname, rdtype, rdclass, response)
  533.         if self.cache:
  534.             self.cache.put((qname, rdtype, rdclass), answer)
  535.         
  536.         return answer
  537.  
  538.     
  539.     def use_tsig(self, keyring, keyname = None):
  540.         self.keyring = keyring
  541.         if keyname is None:
  542.             self.keyname = self.keyring.keys()[0]
  543.         else:
  544.             self.keyname = keyname
  545.  
  546.     
  547.     def use_edns(self, edns, ednsflags, payload):
  548.         if edns is None:
  549.             edns = -1
  550.         
  551.         self.edns = edns
  552.         self.ednsflags = ednsflags
  553.         self.payload = payload
  554.  
  555.  
  556. default_resolver = None
  557.  
  558. def get_default_resolver():
  559.     global default_resolver
  560.     if default_resolver is None:
  561.         default_resolver = Resolver()
  562.     
  563.     return default_resolver
  564.  
  565.  
  566. def query(qname, rdtype = dns.rdatatype.A, rdclass = dns.rdataclass.IN, tcp = False):
  567.     return get_default_resolver().query(qname, rdtype, rdclass, tcp)
  568.  
  569.  
  570. def zone_for_name(name, rdclass = dns.rdataclass.IN, tcp = False, resolver = None):
  571.     if isinstance(name, (str, unicode)):
  572.         name = dns.name.from_text(name, dns.name.root)
  573.     
  574.     if resolver is None:
  575.         resolver = get_default_resolver()
  576.     
  577.     if not name.is_absolute():
  578.         raise NotAbsolute, name
  579.     
  580.     while None:
  581.         
  582.         try:
  583.             answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp)
  584.             return name
  585.         continue
  586.         except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
  587.             
  588.             try:
  589.                 name = name.parent()
  590.             except dns.name.NoParent:
  591.                 raise NoRootSOA
  592.             except:
  593.                 None<EXCEPTION MATCH>dns.name.NoParent
  594.             
  595.  
  596.             None<EXCEPTION MATCH>dns.name.NoParent
  597.         
  598.  
  599.         return None
  600.  
  601.